/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.brain.core.manager;

import com.brain.conf.dto.MonedaDto;
import com.brain.conf.manager.MonedaManager;
import com.brain.core.common.UtilCore;
import com.brain.core.configuracion.WebServletContextListener;
import com.brain.core.dto.EmpresaDto;
import com.brain.core.dto.EmpresaMonedaDto;
import com.brain.core.dto.EmpresaOpcionSistemaDto;
import com.brain.core.dto.OrganizacionDto;

import com.brain.core.exception.DAOException;
import com.brain.core.hibernate.dao.DAOGenerico;
import com.brain.core.view.mbean.ApplicationMBean;
import com.brain.core.view.mbean.ArchivoMBean;
import com.brain.core.view.mbean.SessionMBean;
import com.brain.core.dto.EmpresaUbigeoDto;
import com.brain.core.view.mbean.PropietarioMBean;
import com.brain.core.view.util.ConstantesCore;
import com.brain.segu.dto.RolDto;
import com.brain.segu.dto.UsuarioDto;
import com.brain.segu.manager.OpcionSistemaManager;
import com.brain.segu.manager.RolManager;
import com.brain.segu.manager.UsuarioManager;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.annotation.Resource;
import javax.faces.context.FacesContext;
import javax.servlet.http.HttpServletRequest;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Service;

/**
 *
 * @author Indra
 */
@Service
public class EmpresaManager extends ComunManager<EmpresaDto> implements Serializable {

    private static Logger logger = Logger.getLogger(EmpresaManager.class);
    private Long idEntidad = 101L;
    @Resource
    private DAOGenerico<EmpresaDto> springHibernateDao;
    @Resource
    private RecursosManager recursosManager;
    @Resource
    private RolManager rolManager;
    @Resource
    private OrganizacionManager organizacionManager;
    @Resource
    private UsuarioManager usuarioManager;
    @Resource
    private MonedaManager monedaManager;
    @Resource
    private EmpresaMonedaManager empresaMonedaManager;
    @Resource
    private EmpresaOpcionSistemaManager eosManager;
    @Resource
    private EmpresaUbigeoManager euManager;
    @Resource
    private OpcionSistemaManager opcionSistemaManager;
    private final String url = "/pages/core/empresa/empresa.xhtml";
    private final String urlLista = "/pages/core/empresa/listaEmpresas.xhtml";
    private Long idEmpresaSystem = 3L;
    private EmpresaDto empresaSystem;
    /**
     * UBIGEO*
     */
    private final String UbigeoPadreDescripcion = "UBIGEOS";
    private short UbigeoPadrePrioridad = 9;
    private short UbigeoPadreNivel = 0;
    /**
     * OPCION SISTEMA*
     */
    private final String OpcionsistemaPadreDescripcion = "MENU PRINCIPAL";
    private final String OpcionsistemaPadreTipo = "P";
    private final String OpcionsistemaPadreValor = "menu.principal";
    private final String OpcionsistemaPadreIcono = "ui-icon  ui-icon-gear";
    private final String OpcionsistemaPadreModulo = "SEGU";
    private final short OpcionsistemaPadreOrden = 0;

    /**
     * Metodo para obtener todas las empresas
     *
     * @return lista de empresas
     * @throws DAOException
     */
    public List<EmpresaDto> obtenerTodos() throws DAOException {
        return springHibernateDao.listarTodosDtos(EmpresaDto.class);
    }

    /**
     * Metodo para obtener una empresa por su ID
     *
     * @param id ID de la empresa
     * @return Empresa
     * @throws DAOException
     */
    public EmpresaDto obtenerPorId(Long id) throws DAOException {
        return springHibernateDao.obtenerDtoPorId(EmpresaDto.class, id);
    }

    /**
     * Metodo para obtener empresas por un mapa de filtros
     *
     * @param filtros mapa de filtros
     * @return lista de empresas
     * @throws DAOException
     */
    public List<EmpresaDto> obtenerConFiltro(Map<String, Object> filtros) throws DAOException {
        return springHibernateDao.obtenerDtosConFiltros(EmpresaDto.class, filtros);
    }

    /**
     * Metodo para obtener empresas por un mapa de filtros y un mapa de orden
     *
     * @param filtros mapa de filtros
     * @param orden mapa de orden
     * @return lista de empresas
     * @throws DAOException
     */
    public List<EmpresaDto> obtenerConFiltroConOrden(Map<String, Object> filtros, Map<String, String> orden) throws DAOException {
        return springHibernateDao.obtenerDtosConFiltrosConOrden(EmpresaDto.class, filtros, orden);
    }

    /**
     * Metodo para obtener filtros de acuerdo a un filtro
     *
     * @param dtoFiltro filtros
     * @return lista de empresa
     * @throws DAOException
     */
    public List<EmpresaDto> obtener(EmpresaDto dtoFiltro) throws DAOException {
        SessionMBean sessionMBean = (SessionMBean) WebServletContextListener.getApplicationContext().getBean("sessionMBean");
        String hqsql = "select e from EmpresaDto as e where e.id=e.id ";
        List<Object> listaParametros = new ArrayList<Object>();

        if (dtoFiltro.getId() != null && !dtoFiltro.getId().equals(0L)) {
            hqsql += " and e.id = ?";
            listaParametros.add(dtoFiltro.getId());
        }
        if (dtoFiltro.getDescripcion() != null && dtoFiltro.getDescripcion().length() != 0) {
            hqsql += " and upper(e.descripcion) like '%" + dtoFiltro.getDescripcion().toUpperCase() + "%'";
        }

        //Si no es el Rol System
        if (!sessionMBean.getSessionUsuarioDto().getRolDto().getId().equals(sessionMBean.getRolSystem())) {
            hqsql += " and e.id = ?";
            listaParametros.add(sessionMBean.getEmpresaDto().getId());
        }

        hqsql += " order by e.descripcion asc";
        return springHibernateDao.ejecutarQuery(hqsql, listaParametros);
    }

    /**
     * Metodo que obtiene empresas activas
     *
     * @return lista de empresas
     * @throws DAOException
     */
    public List<EmpresaDto> obtenerActivos() throws DAOException {
        Map<String, Object> filtros = new HashMap<String, Object>();
        filtros.put("estado", Boolean.TRUE);
        Map<String, String> orden = new HashMap<String, String>();
        orden.put("descripcion", "asc");
        return springHibernateDao.obtenerDtosConFiltrosConOrden(EmpresaDto.class, filtros, orden);
    }

    /**
     * Metodo para inicializar los atributos de una empresa
     *
     * @return Empresa inicianilizada
     */
    public EmpresaDto inicializar() {
        ApplicationMBean applicationMBean = (ApplicationMBean) WebServletContextListener.getApplicationContext().getBean("applicationMBean");
        EmpresaDto dto = new EmpresaDto();
        dto = new EmpresaDto();
        dto.setEstado(Boolean.TRUE);
        dto.setPaisDto(applicationMBean.getDefaultPaisDto());
        return dto;
    }

    /**
     * Metodo para guardar una empresa
     *
     * @param dto Empresa a guardar
     * @return Cadena de satisfaccion
     */
    public String guardar(EmpresaDto dto) {

        String to = null;
        String mensajeTrx = "";
        SessionMBean sessionMBean = (SessionMBean) WebServletContextListener.getApplicationContext().getBean("sessionMBean");
        ApplicationMBean applicationMBean = (ApplicationMBean) WebServletContextListener.getApplicationContext().getBean("applicationMBean");


        {
            dto.setUsuarioDto(sessionMBean.getSessionUsuarioDto());
            dto.setFecha(UtilCore.Fecha.obtenerFechaActualDate());
            dto.setTerminal(sessionMBean.getSessionTerminal());
        }

        if (sessionMBean.getAccion() == applicationMBean.getNuevo()) {
            try {
                dto.setUsuarioCreacionDto(sessionMBean.getSessionUsuarioDto());
                dto.setFechaCreacion(UtilCore.Fecha.obtenerFechaActualDate());
                dto.setTerminalCreacion(sessionMBean.getSessionTerminal());
                UtilCore.General.toUpperCaseDto(dto);
                nuevo(dto);
                generarDatosIniciales(dto);
                mensajeTrx = UtilCore.Internacionalizacion.getMensajeInternacional("form.general.mensaje.transaccion.ok");
                recursosManager.showMessage(mensajeTrx);

                to = "";//retroceder();
            } catch (Exception ex) {
                mensajeTrx = ex.getMessage();
                recursosManager.showError(ex.getMessage());
                logger.error(mensajeTrx);

                to = null;
            }
        } else if (sessionMBean.getAccion() == applicationMBean.getEditar()) {

            /*Guardamos el archivo de lo logo*/

            {
                ArchivoMBean archivoMBean = (ArchivoMBean) WebServletContextListener.getApplicationContext().getBean("archivoMBean");

                try {
                    if (dto.getArchivoLogoDto() != null && getIdEntidad() != null) {
                        archivoMBean.grabarArchivo(dto.getArchivoLogoDto(), getIdEntidad(), dto.getId());
                    }
                } catch (FileNotFoundException ex) {
                    recursosManager.showError("ARCHIVO NO ENCONTRADO :: " + ex.getMessage());
                    logger.error(ex);
                } catch (IOException ex) {
                    recursosManager.showError("ERROR DE ENTRADA Y SALIDA :: " + ex.getMessage());
                    logger.error(ex);
                }
            }

            try {
                UtilCore.General.toUpperCaseDto(dto);
                editar(dto);
                mensajeTrx = UtilCore.Internacionalizacion.getMensajeInternacional("form.general.mensaje.transaccion.ok");
                recursosManager.showMessage(mensajeTrx);
                to = "";//retroceder();
            } catch (Exception ex) {
                mensajeTrx = ex.getMessage();
                recursosManager.showError(ex.getMessage());
                logger.error(mensajeTrx);
                to = null;
            }
        }



        return to;
    }

    private void generarDatosIniciales(EmpresaDto dto) {
        HttpServletRequest request = (HttpServletRequest) FacesContext.getCurrentInstance().getExternalContext().getRequest();
        try {
            SessionMBean sessionMBean = (SessionMBean) WebServletContextListener.getApplicationContext().getBean("sessionMBean");
            ParametroManager parametroManager = (ParametroManager) WebServletContextListener.getApplicationContext().getBean("parametroManager");
            //Agregamos como ubigeo por defecto al pais de la empresa
            EmpresaUbigeoDto euDto = new EmpresaUbigeoDto();
            euDto.setEmpresaDto(dto);
            euDto.setUbigeoDto(dto.getPaisDto());
            euManager.nuevo(euDto);
            //Agregamos como opciones de sistema por defecto el Menu principal, MOD SEGU y GEST. EMPRESAS
            EmpresaOpcionSistemaDto eosDto = new EmpresaOpcionSistemaDto();
            eosDto.setEmpresaDto(dto);
            eosDto.setOpcionSistemaDto(opcionSistemaManager.obtenerPorId(opcionSistemaManager.getIdOpcionSistemaPrincipal()));
            eosManager.nuevo(eosDto);
            eosDto = new EmpresaOpcionSistemaDto();
            eosDto.setEmpresaDto(dto);
            eosDto.setOpcionSistemaDto(opcionSistemaManager.obtenerPorId(opcionSistemaManager.getIdOSSeguridad()));
            eosManager.nuevo(eosDto);
            eosDto = new EmpresaOpcionSistemaDto();
            eosDto.setEmpresaDto(dto);
            eosDto.setOpcionSistemaDto(opcionSistemaManager.obtenerPorId(opcionSistemaManager.getIdOSGestionRoles()));
            eosManager.nuevo(eosDto);
            eosDto = new EmpresaOpcionSistemaDto();
            eosDto.setEmpresaDto(dto);
            eosDto.setOpcionSistemaDto(opcionSistemaManager.obtenerPorId(opcionSistemaManager.getIdOSGestionUsuarios()));
            eosManager.nuevo(eosDto);
            eosDto = new EmpresaOpcionSistemaDto();
            eosDto.setEmpresaDto(dto);
            eosDto.setOpcionSistemaDto(opcionSistemaManager.obtenerPorId(opcionSistemaManager.getIdOSConfGeneral()));
            eosManager.nuevo(eosDto);
            eosDto = new EmpresaOpcionSistemaDto();
            eosDto.setEmpresaDto(dto);
            eosDto.setOpcionSistemaDto(opcionSistemaManager.obtenerPorId(opcionSistemaManager.getIdOSGestEmpresa()));
            eosManager.nuevo(eosDto);
            //Generamos el ROL por defecto
            RolDto rolDto = new RolDto();
            rolDto.setDescripcion(UtilCore.Internacionalizacion.getMensajeInternacional("general.rol.por.defecto.desc"));
            rolDto.setDescripcionCorta(UtilCore.Internacionalizacion.getMensajeInternacional("general.rol.por.defecto.desc.corta"));
            rolDto.setActivo(Boolean.TRUE);
            rolDto.setUsuarioDefault(Boolean.TRUE);
            rolDto.setComentario(UtilCore.Internacionalizacion.getMensajeInternacional("general.rol.por.defecto.comentario"));
            rolDto.setFechaCreacion(UtilCore.Fecha.obtenerFechaActualDate());
            rolDto.setUsuarioCreacionDto(sessionMBean.getSessionUsuarioDto());
            rolDto.setFecha(UtilCore.Fecha.obtenerFechaActualDate());
            rolDto.setUsuarioDto(sessionMBean.getSessionUsuarioDto());
            rolDto.setEmpresa(dto.getId());
            rolDto.setAdmin(Boolean.TRUE);
            rolDto.setIsEmpleado(Boolean.FALSE);
            rolDto.setTerminal(request.getRemoteAddr());
            rolDto.setTerminalCreacion(request.getRemoteAddr());
            rolManager.nuevo(rolDto);

            //Generamos el Usuario por defecto 
            UsuarioDto usuarioDto = new UsuarioDto();
            usuarioDto.setLogin(usuarioManager.getLogin());
            usuarioDto.setEstado(Boolean.TRUE);
            if (parametroManager.obtenerPorId(ConstantesCore.Parametro.PARAMETRO_PASSWORD_AUTOGENERADO).getValorBoolean()) {
                usuarioDto.setContrasenaActual(UtilCore.Seguridad.encriptarTexto(UtilCore.Seguridad.getCadenaAlfanumAleatoria(10)));
            } else {
                usuarioDto.setContrasenaActual(UtilCore.Seguridad.encriptarTexto(usuarioManager.getContrasenia()));
            }
            usuarioDto.setBloqueado(Boolean.FALSE);
            usuarioDto.setContrasenaExpirada(Boolean.FALSE);
            usuarioDto.setRolDto(rolDto);
            usuarioDto.setDescripcion(usuarioManager.getUsuarioDesc());
            usuarioDto.setFechaCreacion(UtilCore.Fecha.obtenerFechaActualDate());
            usuarioDto.setUsuarioCreacionDto(sessionMBean.getSessionUsuarioDto());
            usuarioDto.setFecha(UtilCore.Fecha.obtenerFechaActualDate());
            usuarioDto.setUsuarioDto(sessionMBean.getSessionUsuarioDto());
            usuarioDto.setEmpresa(dto.getId());
            usuarioDto.setTerminal(request.getRemoteAddr());
            usuarioDto.setTerminalCreacion(request.getRemoteAddr());
            usuarioManager.nuevo(usuarioDto);
            usuarioDto.setLogin(usuarioDto.getLogin() + usuarioDto.getId());
            usuarioManager.editar(usuarioDto);

            //Generamos el ROL EMPLEADO que servira para el modulo de RRHH
            rolDto = new RolDto();
            rolDto.setDescripcion(UtilCore.Internacionalizacion.getMensajeInternacional("general.rol.empleado.desc"));
            rolDto.setDescripcionCorta(UtilCore.Internacionalizacion.getMensajeInternacional("general.rol.empleado.desc.corta"));
            rolDto.setActivo(Boolean.TRUE);
            rolDto.setUsuarioDefault(Boolean.FALSE);
            rolDto.setComentario(UtilCore.Internacionalizacion.getMensajeInternacional("general.rol.empleado.comentario"));
            rolDto.setFechaCreacion(UtilCore.Fecha.obtenerFechaActualDate());
            rolDto.setUsuarioCreacionDto(sessionMBean.getSessionUsuarioDto());
            rolDto.setFecha(UtilCore.Fecha.obtenerFechaActualDate());
            rolDto.setUsuarioDto(sessionMBean.getSessionUsuarioDto());
            rolDto.setEmpresa(dto.getId());
            rolDto.setAdmin(Boolean.FALSE);
            rolDto.setTerminal(request.getRemoteAddr());
            rolDto.setTerminalCreacion(request.getRemoteAddr());
            rolDto.setIsEmpleado(Boolean.TRUE);
            rolManager.nuevo(rolDto);

            //Generamos la Organizacion por defecto
            OrganizacionDto orgDto = new OrganizacionDto();
            orgDto.setNombre(UtilCore.Internacionalizacion.getMensajeInternacional("general.organizacion.por.defecto.nombre"));
            orgDto.setEmpresaDto(dto);
            orgDto.setEstado(Boolean.TRUE);
            orgDto.setFechaCreacion(UtilCore.Fecha.obtenerFechaActualDate());
            orgDto.setUsuarioCreacionDto(sessionMBean.getSessionUsuarioDto());
            orgDto.setFecha(UtilCore.Fecha.obtenerFechaActualDate());
            orgDto.setUsuarioDto(sessionMBean.getSessionUsuarioDto());
            orgDto.setTerminal(request.getRemoteAddr());
            orgDto.setTerminalCreacion(request.getRemoteAddr());
            organizacionManager.nuevo(orgDto);

            //Generamos el registro por defecto en la tabla propietarios del usuario y organizacion que se acaban de crear
            sessionMBean.setEntidad(usuarioManager.getIdEntidad());
            sessionMBean.setRegistro(usuarioDto.getId());
            PropietarioMBean propietarioMBean = (PropietarioMBean) WebServletContextListener.getApplicationContext().getBean("propietarioMBean");

            propietarioMBean.setOrganizacionDto(orgDto);
            propietarioMBean.setEstado(Boolean.TRUE);
            propietarioMBean.setPrincipal(Boolean.TRUE);
            propietarioMBean.nuevoPropietario();


            //Enviamos el email al usuario administrador

            if (parametroManager.obtenerPorId(ConstantesCore.Parametro.PARAMETRO_NOTIFIC_ENVIAR_EMAIL_CREAR_USUARIO_EMP).getValorBoolean()) {
                usuarioManager.enviarEmail(usuarioDto, "E");
            }
        } catch (Exception ex) {
            recursosManager.showError(ex.getMessage());
            logger.error(ex.getMessage());
        }
    }

    public List<MonedaDto> cargarListaMonedasMaestro(EmpresaDto empresaDto) {
        List<MonedaDto> lstMonedas = null;
        try {
            lstMonedas = monedaManager.obtenerTodosActivos();
            List<EmpresaMonedaDto> lstEmpresaMoneda = empresaMonedaManager.obtenerTodosPorEmpresa(empresaDto);
            for (MonedaDto mDto : lstMonedas) {
                mDto.setIsSelected(Boolean.FALSE);
                for (EmpresaMonedaDto emDto : lstEmpresaMoneda) {
                    if (emDto.getMonedaDto().getId().equals(mDto.getId())) {
                        mDto.setIsSelected(Boolean.TRUE);
                    }
                }
            }
        } catch (Exception ex) {
            recursosManager.showError(ex.getMessage());
            logger.error(ex.getMessage());
        }
        return lstMonedas;
    }

    public static Logger getLogger() {
        return logger;
    }

    public static void setLogger(Logger logger) {
        EmpresaManager.logger = logger;
    }

    public DAOGenerico<EmpresaDto> getSpringHibernateDao() {
        return springHibernateDao;
    }

    public void setSpringHibernateDao(DAOGenerico<EmpresaDto> springHibernateDao) {
        this.springHibernateDao = springHibernateDao;
    }

    public RecursosManager getRecursosManager() {
        return recursosManager;
    }

    public void setRecursosManager(RecursosManager recursosManager) {
        this.recursosManager = recursosManager;
    }

    public Long getIdEmpresaSystem() {
        return idEmpresaSystem;
    }

    public void setIdEmpresaSystem(Long idEmpresaSystem) {
        this.idEmpresaSystem = idEmpresaSystem;
    }

    public EmpresaDto getEmpresaSystem() {
        return empresaSystem;
    }

    public void setEmpresaSystem(EmpresaDto empresaSystem) {
        this.empresaSystem = empresaSystem;
    }

    public String getUrl() {
        return url;
    }

    public String getUrlLista() {
        return urlLista;
    }

    public Long getIdEntidad() {
        return idEntidad;
    }

    public void setIdEntidad(Long idEntidad) {
        this.idEntidad = idEntidad;
    }

    public String getUbigeoPadreDescripcion() {
        return UbigeoPadreDescripcion;
    }

    public short getUbigeoPadrePrioridad() {
        return UbigeoPadrePrioridad;
    }

    public void setUbigeoPadrePrioridad(short UbigeoPadrePrioridad) {
        this.UbigeoPadrePrioridad = UbigeoPadrePrioridad;
    }

    public short getUbigeoPadreNivel() {
        return UbigeoPadreNivel;
    }

    public void setUbigeoPadreNivel(short UbigeoPadreNivel) {
        this.UbigeoPadreNivel = UbigeoPadreNivel;
    }

    public String getOpcionsistemaPadreDescripcion() {
        return OpcionsistemaPadreDescripcion;
    }

    public String getOpcionsistemaPadreTipo() {
        return OpcionsistemaPadreTipo;
    }

    public String getOpcionsistemaPadreValor() {
        return OpcionsistemaPadreValor;
    }

    public String getOpcionsistemaPadreIcono() {
        return OpcionsistemaPadreIcono;
    }

    public String getOpcionsistemaPadreModulo() {
        return OpcionsistemaPadreModulo;
    }

    public short getOpcionsistemaPadreOrden() {
        return OpcionsistemaPadreOrden;
    }
}
